var input = "315679824".ToCharArray().Select(c => int.Parse($"{c}")).ToArray(); var cups = Enumerable.Range(0,input.Length).ToDictionary(e => input[e], e=> input[(e+1)%input.Length]); var currentPosition = cups.First().Key; IEnumerable Play(int moves){ for (int move = 0; move < moves; move++) { var pickedUp = new [] { RemoveAfter(currentPosition), RemoveAfter(currentPosition), RemoveAfter(currentPosition), }; var dest = currentPosition - 1; if (dest < 1) dest = cups.Count; while (pickedUp.Contains(dest)) { dest--; if (dest < 1) dest = cups.Count; } InsertAfter(dest, pickedUp[2]); InsertAfter(dest, pickedUp[1]); InsertAfter(dest, pickedUp[0]); currentPosition = cups[currentPosition]; } return GetCups(1); } IEnumerable GetCups(int start) { var pos = start; for (int i = 0; i < cups.Count; i++) { yield return pos; pos = cups[pos]; } } void InsertAfter(int which, int val){ var nextCup = cups[which]; cups[which]=val; cups[val] = nextCup; } int RemoveAfter(int which){ var nextCup = cups[which]; var followingCup = cups[nextCup]; cups[which] = followingCup; return nextCup; } var part1 = string.Join("",Play(100).Skip(1)); part1.Dump(); input = input.Concat(Enumerable.Range(input.Length+1, 1000000 - input.Length)).ToArray(); cups = Enumerable.Range(0,input.Length).ToDictionary(e => input[e], e=> input[(e+1)%input.Length]); currentPosition = cups.First().Key; var part2 = Play(10000000).Skip(1).Take(2).Select(i => (long)i).Aggregate ((x, y) => x * y); part2.Dump();